home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
clean
/
sun3.lha
/
Sun3
/
Changes0.7to0.8
< prev
next >
Wrap
Text File
|
1992-08-10
|
13KB
|
256 lines
7 Changes and Additions
Compared with the previous release of the Concurrent Clean System (version
0.7) the language Concurrent Clean has changed considerably, especially by
introducing guards for the specification of conditional expressions. Further-
more some more or less cosmetic syntax improvements have been carried through.
Apart from the changes made to the language also some very important additions
have been implemented. The most important addition is the I/O interface.
Libraries have been implemented that contain functions that make the high-
level specification of modern I/O possible in Concurrent Clean. Furthermore
the concept of macro's has been added and a type attribute that makes it
possible to check single-threadedness of objects at compile-time.
In the following sections these changes and additions will be treated briefly.
7.1 Changes
Guarded expressions
In Concurrent Clean version 0.7 one had to use the predefined IF rule to write
down conditional expressions. Unfortunately the use of the IF rule does not
contribute to the readability of a program, especially when a lot of cases
have to be distinguished.
In Concurrent Clean version 0.8 therefore conditional expressions are
specified by means of guards (see section 2.2). For compatibility with older
versions of Concurrent Clean the IF function has been built-in, which means
that it has been removed from the deltaM library and has become part of the
language. This built-in IF function should not be used any more because the
use of guards generally leads to more elegant and (sometimes) more efficient
programs and moreover because applications of the IF function sometimes cannot
be parsed correctly on places where the keywoard 'IF' is also valid.
Example of the use of guards instead of the IF rule. In Concurrent Clean
version 0.7 the third alternative of the Merge function (merge two sorted
lists of integers, remove doubles) looks as follows:
Merge f:[a|b] g:[c|d] -> IF (< a c)
[a | Merge b g]
(IF (= a c)
(Merge f d)
[c | Merge f d]
);
A much more elegant way of defining this function alternative exists in
Concurrent Clean version 0.8:
Merge f:[a|b] g:[c|d] -> [a | Merge b g], IF < a c
-> Merge f d , IF = a c
-> [c | Merge f d];
An important difference between guards and the IF rule is that the IF rule is
a function whereas the concept of guards is a syntactical construct. For
example, when a guarded expression is annotated with {P} or {I} the process
will only be created when the guard evaluates to True. On the other hand, when
then or else part of the IF rule have a process annotation a process will be
started up immediately, because process annotations force the evaluation of
the annotated argument to root normal form. This process will possibly become
a garbage process, of which the root normal form will be removed by the
garbage collector.
As an example the definition of the Filter function for the Sieve of
Eratosthenes is given in old and new syntax. In the old syntax an extra
function Filter' is necessary to prevent the creation of garbage processes:
:: Filter INT [INT] -> [INT];
Filter pr [n|str] -> IF (=I (MOD n pr) 0)
(Filter pr str)
(Filter' pr str);
:: Filter' INT [INT] -> [INT];
Filter' pr str -> [pr | {I} Filter pr str];
When using guards in Concurrent Clean version 0.8 there is no need to worry
about possible garbage processes:
:: Filter INT [INT] -> [INT];
Filter pr [n|str] -> Filter pr str , IF = (% n pr) 0
-> [pr | {I} Filter pr str];
Cosmetic syntax changes
Compared to Concurrent Clean 0.7 some syntax changes have been carried through
that make Concurrent Clean version 0.8 more uniform, straightforward and
readable than its predecessor.
Predefined functions working on integers
In version 0.7 of the Concurrent Clean System almost all predefined functions
working on integers ended with the letter I to distinguish them from
predefined functions for other basic types such as REAL and CHAR. Because the
predefined functions for integers are the most frequently used it has been
decided to drop the I extension for these functions in version 0.8.
Furthermore the predefined function 'MOD' has been changed in to '%'. For a
complete overview of all delta rules the reader is referred to appendix B.
Rule alternatives
In Concurrent Clean 0.8 rule alternatives are separated by a semicolon (';')
instead of a vertical bar ('|').
As an example of the syntax changes the Fac function is given in old
syntax:
Fac 0 -> 1 |
Fac n -> *I n (Fac (--I n));
And in new syntax:
Fac 0 -> 1;
Fac n -> * n (Fac (-- n));
Algebraic type definitions
In Concurrent Clean version 0.7 the left-hand-side of an algebraic type
definition had to be repeated in every alternative of the type:algebraic type.
Alternatives of algebraic types were separated by a vertical bar ('|'). In
version 0.8 the left-hand-side of an algebraic type definition needs to be
specified only once and the alternatives are separated by either an arrow
symbol ('->') or a vertical bar ('|').
As examples of the use of the new syntax for algebraic types the types List
and Bool are given in old and new syntax. In version 0.7 syntax:
:: List x -> Nil |
List x -> Cons x (List x) ;
:: Bool -> True |
Bool -> False ;
In the new syntax this becomes:
:: List x -> Nil
-> Cons x (List x);
:: Bool -> True | False;
From the examples it should be clear how the two separators ('|' and '->') are
meant to be used.
List denotations
In Concurrent Clean version 0.8 it is now possible to prefix a list with more
than one element. This means one can write [a,b,c|rest] instead of
[a|[b|[c|rest]]].
Comments
In Concurrent Clean 0.7 comments had to be preceded with two vertical bars
('||'). When two vertical bars were encountered the rest of that line was
considered to be comment. In version 0.8 there are two ways of specifying
comments. Firstly by preceding it by two equals symbols ('=='), which has the
same meaning as the vertical bars of version 0.7. Secondly it is now possible
to specify comments by means of comment brackets ('<<' and '>>') that can
enclose any number of characters and lines in a Clean program. Comments
enclosed in comment brackets can also be nested. When comment brackets occur
in a string denotation inside bracketed comment this will be parsed correctly
when the string denotation is correct.
7.2 Additions
Macro's
One of the new features of Concurrent Clean version 0.8 is the concept of
macro's. Besides TYPE blocks and RULE blocks now also MACRO blocks may occur
in a Clean module. At compile time the right-hand-side of a macro definition
will be substituted for every occurrence of the left-hand-side of the macro
definition. Macro's may have parameters but it is not allowed to specify a
pattern on the left-hand-side of a macro definition. A macro rule always
consists of a single alternative. It is clear that, at compile-time, the
rewriting of the macros should always terminate. This is guaranteed by
prohibiting macros that are recursive or mutually dependent.
The main reason for implementing macro's is that function definitions that
assign a name to a constant cannot be used as a pattern on the left-hand-side.
Macro's on the other hand can be used as patterns. Furthermore the use of a
macro's instead of non-recursive functions will speed up a Clean program be
cause less function calls need to be done. A disadvantage is that more code
will be generated when (parameterized) macro's are used instead of non-
recursive functions. Some examples of macro's in Concurrent Clean:
MACRO
Size -> 6;
UnsortedList -> [3,1,5,2,4];
Singleton x -> [x];
Pair a b -> (a,b);
+SC string char -> +S string (CTOS char);
*R4 r1 r2 r3 r4 -> *R r1 (*R r2 (*R r3 r4)));
A complete description of the concept of macro's in Concurrent Clean can be
found in section 2.4 of this manual.
Unique types
Nodes of a graph to which there exists at most one path starting from the root
of that graph are called single-threaded or unique. When implementing the I/O
interface for Concurrent Clean the need was felt to have a way to check single-
threadedness or uniqueness of objects at compile-time. In this way a lot of
run-time checks can be omitted, which enhances the efficiency of advanced I/O
in Concurrent Clean. Moreover, for, for example, a future implementation of
arrays in Concurrent Clean a compile-time check on uniqueness can also be very
useful.
Unfortunately, at compile time type:unique typeness is an undecidable
property. In Concurrent Clean version 0.8 therefore a decidable approximation
of uniqueness has been incorporated. For this purpose, types can be supplied
with UNQ (pronounce as 'unique') attributes. Intuitively, this UNQ attribute
enforces that the corresponding actual nodes of the graph will be unique. The
compiler will check whether nodes that are UNQ attributed are indeed used
uniquely. Section 3.6 contains a complete overview of the use and the seman
tics of the UNQ type attribute.
Modern input / output
For Concurrent Clean version 0.8 a sophisticated I/O interface has been
written. The I/O interface is written entirely in Concurrent Clean and is
machine independent. Underneath the I/O Interface only a thin layer of machine
dependent routines has been implemented that forms the interface between the
Macintosh toolbox and Concurrent Clean. Interfaces with other window oriented
operating systems such as XWindows/Open Look are under development. The I/O
interface contains functions to define menu's and dialogues, to draw pictures
and strings, to handle windows and mice etcetera.
Also new I/O:file I/O operations have been implemented (see appendix B, module
deltaFile), which means that the file I/O operations of Concurrent Clean
version 0.7 have been dropped. Because the version 0.8 file I/O operations
only work when concrete code is generated, the version 0.7 file I/O operations
are still supported to be able to do file I/O in the simulator / interpreter
(see appendix B, module deltaIO). In future versions of the language these
operations will not be supported anymore: the new file I/O operations will
then also be available for the simulator / interpreter.
The elegance of the specification of modern I/O in Concurrent Clean has been
achieved by using a new approach to functional I/O. This approach is based on
an explicit environment passing scheme, in which the environment is passed
only to functions that have a side-effect. Unique types have been used to guar
antee single threaded use of the environment. This new approach for functional
I/O is called Concurrent Clean event I/O.
A detailed overview of functional I/O in Concurrent Clean is presented in
chapter 5.
_______________________________
* Warning: The Concurrent Clean System version 0.8 only supports the new I/O
facilities when concrete code is generated. In the interpreter/simulator the
(very limited) I/O features of version 0.7 can still be used to write
"interactive" programs.
* Unique in the sense that there is no other item with the same id. This has
nothing to do with the UNQ type attribute.
* Warning: The Concurrent Clean System version 0.8 only supports parallelism
when the interpreter /simulator is used. Parallel code can already be
generated for a Parsytec Supercluster. For Macintosh and Sun a generator for
parallel code is under development. At the moment parallel annotations are
ignored when concrete code is generated.